package com.zzyl.nursing.util;

import com.zzyl.nursing.vo.member.DeviceDataByDayVo;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 设备数据统计工具类
 */
public class DeviceDataStatisticsUtils {

    /**
     * 将毫秒时间戳转为 LocalDateTime，并向下取整到整点
     */
    public static LocalDateTime convertToHourFloor(Long timestamp) {
        LocalDateTime dt = Instant.ofEpochMilli(timestamp)
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
        return dt.withMinute(0).withSecond(0).withNano(0);
    }

    /**
     * 将毫秒时间戳转为 LocalDateTime，并向下取整到日期（当天的0点0分0秒）
     */
    public static LocalDateTime convertToDayFloor(Long timestamp) {
        LocalDateTime dt = Instant.ofEpochMilli(timestamp)
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
        return dt.withHour(0).withMinute(0).withSecond(0).withNano(0);
    }

    /**
     * 填充缺失小时数据，默认值为 0.0
     */
    public static List<DeviceDataByDayVo> fillMissingHours(LocalDateTime start, LocalDateTime end, 
                                                           List<DeviceDataByDayVo> dbResult) {
        // 转为 Map 便于查找
        Map<String, Double> valueMap = dbResult.stream()
                .collect(Collectors.toMap(
                        DeviceDataByDayVo::getDateTime,
                        DeviceDataByDayVo::getDataValue,
                        (a, b) -> a, // 如果有重复小时，保留第一个
                        HashMap::new
                ));

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:00");
        List<DeviceDataByDayVo> result = new ArrayList<>();

        LocalDateTime current = start;
        while (!current.isAfter(end)) {
            String hourKey = current.format(formatter);
            Double value = valueMap.getOrDefault(hourKey, 0.0);
            result.add(new DeviceDataByDayVo(hourKey, value));
            current = current.plusHours(1);
        }

        return result;
    }

    /**
     * 按天填充缺失数据并转换日期格式
     * @param start 开始时间
     * @param end 结束时间
     * @param dataList 原始数据列表
     * @return 补全后的数据列表，日期格式已转换
     */
    public static List<DeviceDataByDayVo> fillMissingDaysWithFormat(LocalDateTime start, LocalDateTime end, List<DeviceDataByDayVo> dataList) {
        // 转换为日期进行处理
        LocalDate startDate = start.toLocalDate();
        LocalDate endDate = end.toLocalDate();

        // 创建一个Map来存储已有的数据，便于快速查找
        Map<LocalDate, DeviceDataByDayVo> dataMap = new HashMap<>();
        if (dataList != null) {
            for (DeviceDataByDayVo data : dataList) {
                try {
                    LocalDate date = LocalDate.parse(data.getDateTime());
                    dataMap.put(date, data);
                } catch (Exception e) {
                    // 忽略解析失败的数据
                }
            }
        }

        // 生成完整的日期列表并填充数据
        List<DeviceDataByDayVo> result = new ArrayList<>();
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("MM.dd");

        for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
            DeviceDataByDayVo vo;
            if (dataMap.containsKey(date)) {
                // 使用已有的数据
                vo = dataMap.get(date);
            } else {
                // 创建默认数据，值为0
                vo = new DeviceDataByDayVo();
                vo.setDataValue(0.0);
            }
            // 转换日期格式为 MM.dd
            vo.setDateTime(date.format(outputFormatter));
            result.add(vo);
        }

        return result;
    }

}
